package com.timebank.timecoin.config;

import com.timebank.timecoin.properties.FabricProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.gateway.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

/**
 * fabric-gateway 配置类
 * @author shiliuyinzhen
 */
@Configuration
@AllArgsConstructor
@Slf4j
public class FabricConfig {

    @Resource
    private FabricProperties fabricProperties;

    /**
     * gateway
     * @return
     * @throws Exception
     */
    @Bean
    public Gateway gateway() throws Exception {
        //读取证书
        BufferedReader certificateReader = Files.newBufferedReader(Paths.get(fabricProperties.getCertificatePath()), StandardCharsets.UTF_8);
        X509Certificate certificate = Identities.readX509Certificate(certificateReader);
        //读取私钥
        BufferedReader privateKeyReader = Files.newBufferedReader(Paths.get(fabricProperties.getPrivateKeyPath()), StandardCharsets.UTF_8);
        PrivateKey privateKey = Identities.readPrivateKey(privateKeyReader);
        //使用org1中的user1初始化一个网关wallet账户用于连接网络
        Wallet wallet = Wallets.newInMemoryWallet();
        //放进wallet
        wallet.put("user1", Identities.newX509Identity("Org1MSP", certificate, privateKey));
        //获取fabric网络连接对象
        Gateway.Builder builder = Gateway.createBuilder()
                .identity(wallet, "user1")
                .networkConfig(Paths.get(fabricProperties.getNetworkConfigPath()));
        //连接网关
        Gateway gateway = builder.connect();
        log.info("=========================================== connected fabric gateway {} ", gateway);
        //返回网关对象
        return gateway;
    }

    /**
     * 获取通道
     * @param gateway
     * @return
     */
    @Bean
    public Network network(Gateway gateway) {
        return gateway.getNetwork(fabricProperties.getChannelName());
    }

    /**
     * 获取合约
     * @param network
     * @return
     */
    @Bean
    public Contract contract(Network network) {
        return network.getContract(fabricProperties.getContractName());
    }
}